home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / RESOURCE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-07  |  13.2 KB  |  496 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <FCNTL.H>
  9. #include <STDIO.H>
  10. #include <OSBIND.H>
  11. #include <VDI.H>
  12. #include <memory.h>
  13. #include "K_DEFS.H"
  14. #include "RESOURCE.H"
  15. #include "XA_GLOBL.H"
  16. #include "XA_DEFS.H"
  17. #include "XA_TYPES.H"
  18.  
  19. /*
  20.     RESOURCE FILE HANDLER
  21.  
  22.     Simulate the standard GEM AES resource access functions.
  23.     
  24.     I've added these to Steve's routines to act as a bit of an interface
  25.     to his routines. Each application has it's own std_resource as part
  26.     of the XA_CLIENT structure. As Steve's resource loader is happy to
  27.     allow multiple resource files, I should add some extra calls to support it.
  28. */
  29.  
  30.  
  31. unsigned long XA_rsrc_load(short clnt_pid,AESPB *pb)
  32. {
  33.     XA_CLIENT *client=Pid2Client(clnt_pid);
  34.     char *n=(char*)(pb->addrin[0]);
  35.     char full_path[180];
  36.     short f;
  37.  
  38. /* If the client is overwriting it's existing resource then better free it
  39.      (it shouldn't, but just in case) */
  40. /* I don't think this is a good idea - much better to have a memory leak
  41.     than a process continuing to access a free'd memory region; GEM AES
  42.     doesn't auto-free an existing RSC either, so this would be
  43.     incompatible anyway... <mk>
  44. */
  45. #if 0
  46.      if (client->std_resource)
  47.          FreeResources(client->std_resource);
  48. #endif
  49.  
  50. /* What sort of path is it? */
  51.     for(f=0; (n[f])&&(n[f]!='\\'); f++);
  52.     if (n[f])
  53.         sprintf(full_path,"%s",n);
  54.     else
  55.         sprintf(full_path,"%s\\%s",client->home_path,n);
  56.  
  57.     DIAGS(("rsrc_load('%s')\n",full_path));
  58.  
  59.     client->std_resource=LoadResources(full_path, DU_RSX_CONV, DU_RSY_CONV);
  60.     if (client->std_resource)
  61.         pb->intout[0]=1;
  62.     else
  63.         pb->intout[0]=0;
  64.  
  65.     DIAGS((" LoadResources returned %d\n",client->std_resource));
  66.  
  67. /* Fill in the application's global array with a pointer to the resource */
  68.     *((unsigned long *)&client->globl_ptr[5]) = (unsigned long)((RSHDR*)client->std_resource)->rsh_trindex + (unsigned long)client->std_resource;
  69.     *((unsigned long *)&client->globl_ptr[7]) = (unsigned long)client->std_resource;
  70.  
  71.     return XAC_DONE;
  72. }
  73.  
  74. unsigned long XA_rsrc_free(short clnt_pid,AESPB *pb)
  75. {
  76.     XA_CLIENT *client=Pid2Client(clnt_pid);
  77.     
  78.     if (client->std_resource)
  79.     {
  80.         FreeResources(client->std_resource);
  81.         client->std_resource=NULL;
  82.         pb->intout[0]=1;
  83.     }else{
  84.         pb->intout[0]=0;
  85.     }
  86.  
  87.     return XAC_DONE;
  88. }
  89.  
  90. unsigned long XA_rsrc_gaddr(short clnt_pid,AESPB *pb)
  91. {
  92.     XA_CLIENT *client=Pid2Client(clnt_pid);
  93.     OBJECT **tree_addr;
  94.     char **text_addr;
  95.     void **image_addr,**glob;
  96.     short type=pb->intin[0], index=pb->intin[1];
  97.  
  98.     if (!client->std_resource)
  99.     {
  100.         glob=(void**)(client->globl_ptr+7);
  101.         client->std_resource=*glob;
  102.     }
  103.     
  104.     switch(type)
  105.     {
  106.         case R_TREE:
  107.             tree_addr=(OBJECT**)pb->addrout;
  108.             *tree_addr=ResourceTree(client->std_resource,index);
  109.             break;
  110.         case R_STRING:
  111.             text_addr=(char**)pb->addrout;
  112.             *text_addr=ResourceString(client->std_resource,index);
  113.             break;
  114.         case R_IMAGEDATA:
  115.             image_addr=(void**)pb->addrout;
  116.             *image_addr=ResourceImage(client->std_resource,index);
  117.             break;
  118.     }
  119.     
  120.     if (pb->addrout[0])
  121.         pb->intout[0]=1;
  122.     else
  123.         pb->intout[0]=0;
  124.         
  125.     return XAC_DONE;
  126. }
  127.  
  128. /*
  129.  *    Fixup OBJECT coordinates; the lower byte contains a (character-based)
  130.  *    coordinate, the upper byte an additional (pixel) offset.
  131.  */
  132. #define fixup(val,scale) (((val)&0xff)*(scale)+(((val)>>8)&0xff))
  133.  
  134. void obfix(OBJECT *tree, short object)
  135. {
  136.     OBJECT *o = &tree[object];
  137.  
  138.     o->ob_x = fixup(o->ob_x, display.c_max_w) ;
  139.     o->ob_y = fixup(o->ob_y, display.c_max_h) ;
  140.     /*
  141.     * Special case handling: any OBJECT 80 characters wide is supposed
  142.     * to be a menu bar, which always covers the entire screen width...
  143.     */
  144.     o->ob_width = (o->ob_width==80) ?
  145.             display.w : fixup(o->ob_width, display.c_max_w) ;
  146.     o->ob_height = fixup(o->ob_height, display.c_max_h) ;
  147. }
  148.  
  149. unsigned long XA_rsrc_obfix(short clnt_pid,AESPB *pb)
  150. {
  151.     obfix((OBJECT*)pb->addrin[0],pb->intin[0]);
  152.     pb->intout[0]=1;
  153.     return XAC_DONE;
  154. }
  155.  
  156. /*
  157.     Code in this module is based on the resource loader from
  158.     Steve Sowerby's AGiLE library. Thanks to Steve for allowing
  159.     me to use his code.
  160. */
  161.  
  162. short resWidth,resHeight;
  163.  
  164. /*
  165.     FixColourIconData : Convert a colour icon from device independent to device specific
  166. */
  167. static void FixColourIconData(CICONBLK *icon)
  168. {
  169.     CICON *c;
  170.     MFDB src,dst;
  171.     unsigned long len=(((icon->monoblk.ib_wicon+15)>>3)&~1) * icon->monoblk.ib_hicon;
  172.     unsigned long old_len,new_len,l;
  173.     short *new_data;
  174.  
  175.     for(c=icon->mainlist; c; c=c->next_res)
  176.     {
  177.         
  178.         if (c->num_planes<display.planes)
  179.         {
  180.             old_len  = c->num_planes * len;
  181.             new_len = display.planes * len;
  182.         
  183.             new_data = (short*)Mxalloc(new_len+10,MX_STRAM);
  184.             
  185.             for(l=0; l<(old_len+1)>>1; l++)
  186.                 new_data[l]=c->col_data[l];
  187.             for(; l<(new_len+1)>>1; l++)
  188.                 new_data[l]=0;
  189.             
  190.             c->col_data=new_data;
  191.         }
  192.         
  193.         src.fd_w = icon->monoblk.ib_wicon;                /*Transform standard icon*/
  194.         src.fd_h = icon->monoblk.ib_hicon;
  195.         src.fd_wdwidth = icon->monoblk.ib_wicon>>4;
  196.         src.fd_stand = 1;
  197.         src.fd_r1 = src.fd_r2 = src.fd_r3 = 0;
  198.         src.fd_nplanes = display.planes;
  199.         src.fd_addr = c->col_data;
  200.         dst = src;
  201.         dst.fd_stand = 0;
  202.         vr_trnfm(V_handle,&src,&dst);
  203.  
  204.         if (c->sel_data)                            /*Transform selected icon if exists*/
  205.         {
  206.             
  207.             if (c->num_planes<display.planes)
  208.             {
  209.                 old_len  = c->num_planes * len;
  210.                 new_len = display.planes * len;
  211.             
  212.                 new_data = (short*)Mxalloc(new_len+10,MX_STRAM);
  213.                 
  214.                 for(l=0; l<(old_len+1)>>1; l++)
  215.                     new_data[l]=c->sel_data[l];
  216.                 for(; l<(new_len+1)>>1; l++)
  217.                     new_data[l]=0;
  218.             
  219.                 c->sel_data=new_data;
  220.             }
  221.             
  222.             src.fd_w = icon->monoblk.ib_wicon;
  223.             src.fd_h = icon->monoblk.ib_hicon;
  224.             src.fd_wdwidth = icon->monoblk.ib_wicon>>4;
  225.             src.fd_stand = 1;
  226.             src.fd_r1 = src.fd_r2 = src.fd_r3 = 0;
  227.             src.fd_nplanes = display.planes;
  228.             src.fd_addr = c->sel_data;
  229.             dst = src;
  230.             dst.fd_stand = 0;
  231.             
  232.             vr_trnfm(V_handle,&src,&dst);
  233.         }
  234.     }
  235. }
  236.  
  237. /*
  238.     LoadResources : Load a GEM resource file
  239.     fname = name of file to load
  240.     Return = base pointer of resources or NULL on failure
  241. */
  242. void *LoadResources(char *fname,short designWidth,short designHeight)
  243. {
  244.     long err;
  245.     short handle;
  246.     RSHDR hdr;
  247.     OBJECT *obj,*tree;
  248.     TEDINFO *ti;
  249.     ICONBLK *ib;
  250.     CICONBLK *cib,**cibh;
  251.     BITBLK *bb;
  252.     CICON *cicn,*pcicn;
  253.     unsigned long osize,size,*index,*addr,*earray;
  254.     char *base,*ptext;
  255.     short i,j,type,numCibs=0,numRez,*pdata;
  256.  
  257.     resWidth = display.c_max_w;
  258.     resHeight = display.c_max_h;
  259.     
  260.     DIAGS(("LoadResources(%s)\n",fname));
  261.     
  262.     err = Fopen(fname,O_RDONLY);
  263.     if (err<0L)
  264.     {
  265.         DIAGS(("LoadResources():file not found\n"));
  266.         return NULL;
  267.     }
  268.     handle = (short)err;
  269.     Fread(handle,sizeof(RSHDR),&hdr);
  270.     size = (unsigned long)hdr.rsh_rssize;
  271.     osize = (size+1UL)&0xfffffffeUL;
  272.     if (hdr.rsh_vrsn&4)
  273.     { /* Extended format, get new 32-bit length */
  274.         Fseek(osize,handle,SEEK_SET);
  275.         Fread(handle,4L,&size);
  276.         DIAGS(("extended format: read extended size=%ld\n",size));
  277.     }
  278.     Fseek(0L,handle,SEEK_SET);
  279.     base = (char*)Mxalloc(size+100,MX_STRAM);
  280.     if (!base)
  281.     {
  282.         DIAGS(("Cann't allocate space for resource file\n"));
  283.         Fclose(handle);
  284.         return NULL;
  285.     }
  286.     Fread(handle,size,base);
  287.     Fclose(handle);
  288.  
  289.     ti = (TEDINFO*)(base+(unsigned long)hdr.rsh_tedinfo);
  290.     for (i=0;i<hdr.rsh_nted;i++,ti++)
  291.     { /* Correct all tedinfo field pointers */
  292.         ti->te_ptext = (char*)((unsigned long)ti->te_ptext+base);
  293.         ti->te_ptmplt = (char*)((unsigned long)ti->te_ptmplt+base);
  294.         ti->te_pvalid = (char*)((unsigned long)ti->te_pvalid+base);
  295.     }
  296.  
  297.     DIAGS(("fixed tedinfo's\n"));
  298.  
  299.     ib = (ICONBLK*)(base+(unsigned long)hdr.rsh_iconblk);
  300.     for (i=0;i<hdr.rsh_nib;i++,ib++)
  301.     { /* Correct all iconblk field pointers */
  302.         ib->ib_pmask = (short*)((unsigned long)ib->ib_pmask+base);
  303.         ib->ib_pdata = (short*)((unsigned long)ib->ib_pdata+base);
  304.         ib->ib_ptext = (char*)((unsigned long)ib->ib_ptext+base);
  305.     }
  306.     
  307.     DIAGS(("fixed iconblk's\n"));
  308.  
  309.     bb = (BITBLK*)(base+(unsigned long)hdr.rsh_bitblk);
  310.     for (i=0;i<hdr.rsh_nbb;i++,bb++) /* Correct all bitblk data pointers */
  311.         bb->bi_pdata = (short*)((unsigned long)bb->bi_pdata+base);
  312.  
  313.     DIAGS(("fixed bitblk's\n"));
  314.  
  315.     if (hdr.rsh_vrsn&4)
  316.     { /* It's an enhanced RSC file */
  317.  
  318.         DIAGS(("Enhanced resource file\n"));
  319.  
  320.         earray = (unsigned long*)(osize+(long)base);
  321.  
  322.         cibh = (CICONBLK**)(earray[1]+(long)base);
  323.         if ((long)cibh>0L)
  324.         { /* Get colour icons */
  325.         
  326.             while (*cibh++!=(CICONBLK*)-1L)
  327.                 numCibs++;
  328.  
  329.             cib = (CICONBLK*)cibh;
  330.             cibh = (CICONBLK**)(earray[1]+(long)base);
  331.             for (i=0;i<numCibs;i++)
  332.             { /* Fix up all the CICONBLK's */
  333.                 cibh[i] = cib;
  334.                 ib = &cib->monoblk;
  335.                 size = 2UL*(unsigned long)(ib->ib_wicon/16)*(unsigned long)ib->ib_hicon;
  336.                 addr = (unsigned long*)((long)cib+sizeof(ICONBLK));
  337.                 numRez = (short)*addr;
  338.                 pdata = (short*)&addr[1];
  339.                 ib->ib_pdata = pdata;
  340.                 ib->ib_pmask = (short*)((long)pdata+size);
  341.                 ptext = (char*)((long)pdata+size*2L);
  342.                 ib->ib_ptext = ptext;
  343.                 ptext[11] = 0;
  344.                 cicn = (CICON*)((long)ptext+12L);
  345.                 cib->mainlist = cicn;
  346.                 for (j=0;j<numRez;j++)
  347.                 { /* Get CICON's at different rez's */
  348.                     pcicn = cicn;
  349.                     pdata = (short*)((long)cicn+sizeof(CICON));
  350.                     cicn->col_data = pdata;
  351.                     cicn->col_mask = (short*)((long)pdata+size*(unsigned long)cicn->num_planes);
  352.                     if (cicn->sel_data!=NULL)
  353.                     { /* It's got a selected form */
  354.                         cicn->sel_data = (short*)((long)cicn->col_mask+size);
  355.                         cicn->sel_mask = (short*)((long)cicn->sel_data+size*(unsigned long)cicn->num_planes);
  356.                         cicn = (CICON*)((long)pcicn+sizeof(CICON)+2L*size*((unsigned long)pcicn->num_planes+1L));
  357.                     }
  358.                     else
  359.                     { /* No selected version */
  360.                         cicn->sel_data = cicn->sel_mask = NULL;
  361.                         cicn = (CICON*)((long)pcicn+sizeof(CICON)+size*((unsigned long)pcicn->num_planes+1L));
  362.                     }
  363.                     if (pcicn->next_res==(CICON*)1L)
  364.                         pcicn->next_res = cicn;
  365.                     else
  366.                         pcicn->next_res = NULL;
  367.                 }
  368.                 cib = (CICONBLK*)cicn;
  369.             }
  370.             DIAGS(("done fixing cicons\n"));
  371.         }
  372.     }
  373.  
  374.     obj = (OBJECT*)(base+(unsigned long)hdr.rsh_object);
  375.     for (i=0;i<hdr.rsh_nobs;i++,obj++)
  376.     { /* Correct all objects' ob_spec pointers */
  377.         type = obj->ob_type&255;
  378.         switch (type)
  379.         { /* What kind of object is it? */
  380.             case G_TEXT:
  381.             case G_BOXTEXT:
  382.             case G_IMAGE:
  383.             case G_BUTTON:
  384.             case G_STRING:
  385.             case G_FTEXT:
  386.             case G_FBOXTEXT:
  387.             case G_ICON:
  388.             case G_TITLE:
  389.                 obj->ob_spec = (void*)((unsigned long)obj->ob_spec+base);
  390.                 break;
  391.             case G_CICON:
  392.                 FixColourIconData(cibh[(long)obj->ob_spec]);
  393.                 obj->ob_spec = cibh[(long)obj->ob_spec];
  394.                 break;
  395.             case G_PROGDEF:
  396.                 obj->ob_spec = NULL;
  397.                 break;
  398.             case G_IBOX:
  399.             case G_BOX:
  400.             case G_BOXCHAR:
  401.                 break;
  402.             default:
  403.                 DIAGS(("Unknown object type\r\n"));
  404.                 break;
  405.         }
  406.     }
  407.  
  408.     DIAGS(("fixed ob_spec's:num_obj=%d\n",hdr.rsh_nobs));
  409.  
  410.     index = (unsigned long*)(base+(unsigned long)hdr.rsh_trindex);
  411.     for (i=0;i<hdr.rsh_ntree;i++,index++)
  412.     {
  413.         tree = obj = (OBJECT*)(*index+(unsigned long)base);
  414.         if ((obj[3].ob_type&255)!=G_TITLE) /* Not a menu tree */
  415.             do { /* Fix all object coordinates */
  416.                 obj->ob_x = (((obj->ob_x&255)*designWidth+(obj->ob_x>>8))*resWidth)/designWidth;
  417.                 obj->ob_y = (((obj->ob_y&255)*designHeight+(obj->ob_y>>8))*resHeight)/designHeight;
  418.                 obj->ob_width = (((obj->ob_width&255)*designWidth+(obj->ob_width>>8))*resWidth)/designWidth;
  419.                 obj->ob_height = (((obj->ob_height&255)*designHeight+(obj->ob_height>>8))*resHeight)/designHeight;
  420.             } while (!(obj++->ob_flags&LASTOB));
  421.         else
  422.         { /* Standard AES menu */
  423.             j = 0;
  424.             do { /* Use conventional AES routine */
  425. /*                rsrc_obfix(tree,j);        // GEMAES */
  426.             } while (!(tree[j++].ob_flags&LASTOB));
  427.         }
  428.     }
  429.     
  430.     return (void*)base;
  431. }
  432.  
  433.  
  434. /*
  435.     FreeResources : Dispose of a set of loaded resources
  436.     base = pointer to base of resources
  437. */
  438. void FreeResources(void *base)
  439. {
  440.     Mfree(base);
  441. }
  442.  
  443.  
  444. /*
  445.     ResourceTree : Find the tree with a given index
  446.     base = pointer to base of resources
  447.     num = index number of tree
  448.     Return = pointer to tree or NULL on failure
  449. */
  450. OBJECT *ResourceTree(void *base,short num)
  451. {
  452.     unsigned long *index,offset;
  453.     RSHDR *hdr = (RSHDR*)base;
  454.  
  455.     if ((!hdr)||(num<0)||(num>=hdr->rsh_ntree))
  456.         return NULL;
  457.     index = (unsigned long*)((unsigned long)base+(unsigned long)hdr->rsh_trindex);
  458.     offset = index[num];
  459.     return (OBJECT*)((unsigned long)base+offset);
  460. }
  461.  
  462. /* ResourceString : Find the string with a given index
  463.     base = pointer to base of resources
  464.     num = index number of string
  465.     Return = pointer to string or NULL on failure
  466. */
  467. char *ResourceString(void *base,short num)
  468. {
  469.     unsigned long *index,offset;
  470.     RSHDR *hdr = (RSHDR*)base;
  471.  
  472.     if (!(hdr)||(num<0)||(num>=hdr->rsh_nstring))
  473.         return(NULL);
  474.     index = (unsigned long*)((unsigned long)base+(unsigned long)hdr->rsh_frstr);
  475.     offset = index[num];
  476.     return((char*)((unsigned long)base+offset));
  477. }
  478.  
  479. /*
  480.     ResourceImage : Find the image with a given index
  481.     base = pointer to base of resources
  482.     num = index number of image
  483.     Return = pointer to image or NULL on failure
  484. */
  485. void *ResourceImage(void *base,short num)
  486. {
  487.     unsigned long *index,offset;
  488.     RSHDR *hdr = (RSHDR*)base;
  489.  
  490.     if ((!hdr)||(num<0)||(num>=hdr->rsh_nimages))
  491.         return(NULL);
  492.     index = (unsigned long*)((unsigned long)base+(unsigned long)hdr->rsh_frimg);
  493.     offset = index[num];
  494.     return((void*)((unsigned long)base+offset));
  495. }
  496.